#include <iostream>
using namespace std;
/*
    模板类
    1.概念: 只要类中用到了模板--》 就是模板类

    2.定义:
    (1)模板类显式具体化的语法
            template<typename T>
            class Array               //除string之外的其他类型
            {

            }
            template<>
            class Array<string> //专门针对string的 Array<string>
            {
                具体代码
            }
    举例： 请你定义一个类，该类可以给任何合法类型的指针申请n个类型大小的堆空间
*/

struct Student
{
    string name;
    int age;
};

template <typename T>
class Aipoint
{
public:
    Aipoint(int n)
    {
        cout << "Aipoint(int n)" << endl;
        len = n;
        p = new T[n];
    }
    ~Aipoint()
    {
        cout << "~Aipoint()" << endl;
        delete[] p;
    }

    // 给下标赋值
    void setValue(int index, T value)
    {
        if (index >= 0 && index <= len - 1)
            p[index] = value;
    }
    void show()
    {
        for (int i = 0; i < len; i++)
        {
            cout << p[i] << " ";
        }
        cout << endl;
    }

private:
    T *p;
    int len;
};

template <>
class Aipoint<struct Student> // 专门针对Student的 Aipoint<Student>
{
public:
    Aipoint(int n)
    {
        cout << "Aipoint(int n)" << endl;
        len = n;
        p = new Student[n];
    }
    ~Aipoint()
    {
        cout << "~Aipoint()" << endl;
        delete[] p;
    }

    // 给下标赋值
    void setValue(int index, struct Student value)
    {
        p[index].age = value.age;
        p[index].name = value.name;
    }

    void show()
    {
        for (int i = 0; i < len; i++)
        {
            cout << p[i].name << " " << p[i].age << " ";
        }
        cout << endl;
    }

private:
    struct Student *p;
    int len;
};

int main()
{
    Aipoint<int> a(10); // 模板类创建对象，必须传递模板参数，T就是int
    for (int i = 0; i < 10; i++)
    {
        a.setValue(i, i);
    }
    a.show();

    // Aipoint<double> b(10); // 模板类创建对象，必须传递模板参数，T就是double

    struct Student s1 = {"张三", 10};
    struct Student s2 = {"李四", 20};
    struct Student s3 = {"王五", 30};

    Aipoint<Student> c(3); // 模板类创建对象，必须传递模板参数，T就是Student

    c.setValue(0, s1);
    c.setValue(1, s2);
    c.setValue(2, s3);
    c.show();

    return 0;
}